/**
 * event subscribe/publish
*/

const eventBus = {
  events: {}, // event list
  on(name, cb, times) {
    if (typeof name !== 'string' || typeof cb !== 'function') {
      console.warn('bind error!');
      return;
    }
    const { key, space } = this.splitName(name);
    if (this.events[key]) {
      this.events[key].push({ cb, space, times, done: 0 });
    } else {
      this.events[key] = [{ cb, space, times, done: 0 }];
    }
  },
  emit(name, data) {
    if (typeof name !== 'string') {
      console.warn('emit error!');
      return;
    }
    const { key, space } = this.splitName(name);
    const eventList = this.events[key];
    if (!eventList) return;
    const newList = [];
    for (const item of eventList) {
      if (space) {
        if (item.space === space) {
          item.cb && item.cb(data);
          item.done += 1;
        }
      } else {
        item.cb && item.cb(data);
        item.done += 1;
      }
      if (item.times && item.done >= item.times) {
        continue;
      }
      newList.push(item);
    }
    this.events[key] = newList;
  },
  off(name) {
    if (typeof name !== 'string') {
      console.warn('unbound error!');
      return;
    }
    const { key, space } = this.splitName(name);
    if (!space) {
      this.events[key] = null;
    } else {
      const eventList = this.events[key];
      const newList = [];
      for (const item of eventList) {
        if (item.space !== space) {
          newList.push(item)
        }
      }
      this.events[key] = newList;
    }
  },
  splitName(str) {
    if (str.indexOf('.') > 0) {
      str = str.split('.');
      return { key: str[0], space: str[1] }
    }
    return { key: str }
  }
}

export default eventBus;